package org.kfish.framework.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 反射工具类
 * 
 * @author CK
 *
 */
public class ReflectionUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(ReflectionUtil.class);

	/**
	 * 创建实例
	 */
	public static Object newInstance(Class<?> cls) {

		Object instance = null;

		try {
			instance = cls.newInstance();
		} catch (InstantiationException e) {
			LOGGER.error("new instance failure.", e);
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			LOGGER.error("new instance failure.", e);
			throw new RuntimeException(e);
		}
		return instance;
	}

	/**
	 * 调用方法
	 */
	public static Object invokeMethod(Object obj, Method method, Object... args) {

		Object rslt = null;
		// 防止访问到私有方法时，无法访问
		method.setAccessible(true);
		try {
			//将无法匹配上的参数赋值为空
			int paramCount = method.getParameterCount();
			Object[] parameters = new Object[paramCount];
			int len = Math.min(paramCount, args.length);
			
			for(int i=0;i<len;i++){
				parameters[i] = args[i];
			}
			rslt = method.invoke(obj, parameters);
			
		} catch (IllegalAccessException e) {
			LOGGER.error("invoke method failure.", e);
			throw new RuntimeException(e);
		} catch (IllegalArgumentException e) {
			LOGGER.error("invoke method failure.", e);
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			LOGGER.error("invoke method failure.", e);
			throw new RuntimeException(e);
		}
		return rslt;

	}

	public static void setField(Object obj, Field field, Object value) {
		// 防止访问到私有方法时，无法访问
		field.setAccessible(true);
		try {
			field.set(obj, value);
		} catch (IllegalArgumentException e) {
			LOGGER.error("set field failure.", e);
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			LOGGER.error("set field failure.", e);
			throw new RuntimeException(e);
		}
	}
}
